#ifndef __HJ_LOG_H__
#define __HJ_LOG_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdarg.h>

typedef enum {
    HJ_LOG_LEVEL_FATAL = 0,
    HJ_LOG_LEVEL_ERROR,
    HJ_LOG_LEVEL_WARN,
    HJ_LOG_LEVEL_INFO,
    HJ_LOG_LEVEL_DEBUG,
    HJ_LOG_LEVEL_TRACE,
    HJ_LOG_LEVEL_ALL
} log_level_t;

typedef void (* log_print)(int level, const char *timestamp, const char *file, const char *func, \
                            int line, const char *fmt, va_list args);
typedef struct {
    int level;
    FILE *fp;
    char log_file[1024];
    log_print log_print;
    log_print user_log_print;
} log_conf_t;

/*--------------------------用户控制宏-------------------------*/
#define EN_SHOW_COLOR               1
#define EN_SAVE_TO_FILE             0
#define EN_CACHE_BUFFER             1
#define EN_SHOW_TIME                1
#define HJ_LOG_FILE_NAME            "hj_log.txt"
#define HJ_LOG_FILE_SIZE            1024 // Byte
#define HJ_LOG_LEVEL_USER           HJ_LOG_LEVEL_INFO
#define HJ_LOG_LEVEL_DEFAULT        HJ_LOG_LEVEL_ALL
/*----------------------------end-----------------------------*/

#define HJ_LOG_BLACK 30
#define HJ_LOG_RED 31
#define HJ_LOG_GREEN 32
#define HJ_LOG_YELLOW 33

#define HJ_LOG_BLUE 34
#define HJ_LOG_PURPLE 35
#define HJ_LOG_DARK_GREEN 36
#define HJ_LOG_WHITE 37

#if EN_SHOW_TIME
#define TIMESTAMP hj_get_timestamp()
#else
#define TIMESTAMP ""
#endif


/*--------------------------log等级输出宏定义控制----------------------------------------------------------*/
#if HJ_LOG_LEVEL_DEFAULT >= HJ_LOG_LEVEL_FATAL
#define LOG_FATAL_DEF(...) do{hj_log_print(HJ_LOG_LEVEL_FATAL, TIMESTAMP, __FILE__, __func__, __LINE__, __VA_ARGS__);}while(0)
#else
#define LOG_FATAL_DEF(...)
#endif

#if HJ_LOG_LEVEL_DEFAULT >= HJ_LOG_LEVEL_ERROR
#define LOG_ERROR_DEF(...) do{hj_log_print(HJ_LOG_LEVEL_ERROR, TIMESTAMP, __FILE__, __func__, __LINE__, __VA_ARGS__);}while(0)
#else
#define LOG_ERROR_DEF(...)
#endif

#if HJ_LOG_LEVEL_DEFAULT >= HJ_LOG_LEVEL_WARN
#define LOG_WARN_DEF(...) do{hj_log_print(HJ_LOG_LEVEL_WARN, TIMESTAMP, __FILE__, __func__, __LINE__, __VA_ARGS__);}while(0)
#else
#define LOG_WARN_DEF(...)
#endif

#if HJ_LOG_LEVEL_DEFAULT >= HJ_LOG_LEVEL_INFO
#define LOG_INFO_DEF(...) do{hj_log_print(HJ_LOG_LEVEL_INFO, TIMESTAMP, __FILE__, __func__, __LINE__, __VA_ARGS__);}while(0)
#else
#define LOG_INFO_DEF(...)
#endif

#if HJ_LOG_LEVEL_DEFAULT >= HJ_LOG_LEVEL_DEBUG
#define LOG_DEBUG_DEF(...) do{hj_log_print(HJ_LOG_LEVEL_DEBUG, TIMESTAMP, __FILE__, __func__, __LINE__, __VA_ARGS__);}while(0)
#else
#define LOG_DEBUG_DEF(...)
#endif

#if HJ_LOG_LEVEL_DEFAULT >= HJ_LOG_LEVEL_TRACE
#define LOG_TRACE_DEF(...) do{hj_log_print(HJ_LOG_LEVEL_TRACE, TIMESTAMP, __FILE__, __func__, __LINE__, __VA_ARGS__);}while(0)
#else
#define LOG_TRACE_DEF(...)
#endif

/*--------------------------log宏定义----------------------------------------------------------*/
#define LOG_FATAL(...) LOG_FATAL_DEF(__VA_ARGS__)
#define LOG_ERROR(...) LOG_ERROR_DEF(__VA_ARGS__)
#define LOG_WARN(...) LOG_WARN_DEF(__VA_ARGS__)
#define LOG_INFO(...) LOG_INFO_DEF(__VA_ARGS__)
#define LOG_DEBUG(...) LOG_DEBUG_DEF(__VA_ARGS__)
#define LOG_TRACE(...) LOG_TRACE_DEF(__VA_ARGS__)

char *hj_get_timestamp(void);
void hj_log_print(int level, const char *time_stamp, const char *file, const char *func, \
int line, const char *fmt, ...);


#ifdef __cplusplus
}
#endif 

#endif /* __HJ_LOG_H__ */
